Introduction

The descriptions of the indicators and monitoring frameworks come from this UN document.

Both of these indicators are part of Sustainable Development Goal 11: Make cities and human settlements inclusive, safe, resilient and sustainable.

Admin

Load packages, write utility functions, set options

source("~scripts/00 - Admin.R") 
## Warning: package 'ggplot2' was built under R version 4.0.2
## Warning: package 'tibble' was built under R version 4.0.2
## Warning: package 'osmplotr' was built under R version 4.0.2
source("~scripts/01 - Utility Functions.R")

tmap_mode("view")
tmap_options(basemaps = "Stamen.Terrain")

Transit SDG (11.2.1)

SDG target 11.2 is By 2030, provide access to safe, affordable, accessible and sustainable transport systems for all, improving road safety, notably by expanding public transport, with special attention to the needs of those in vulnerable situations, women, children, persons with disabilities and older persons. Source.

In separate reports, the UN has proposed two different indicators:

  1. Report 1: Proportion of population that has convenient access to public transport, by sex, age and persons with disabilities.
  2. Report 2: Percentage of people within 0.5 km of public transit running at least every 20 minutes

Method

What percentages of the total populations of Baltimore, Minneapolis, and New Orleans proper have access to public transit?

Public transit includes stops, platforms, and/or terminals for any buses, trams / trolleys / streetcars, light rail, metros / subways, and ferries mapped in OpenStreetMap for the cities. Access includes having at least one such stop, platform, or terminal within 0.5km (defined three different ways, described below).

Note that the UN indicator stipulates that the transit run at least every 20 minutes, but headway information (stored in the interval=* tag) is not well populated on OSM - only about 8,000 total uses globally compared to over 190,000 bus routes mapped. Incorporating headways into the analysis requires an external reference dataset such as transit agency GTFS feeds (using reference datasets probably relevant for the completion metrics work).

Methodology (for each city):

  1. Download census block groups with population

  2. Split into 1/10th square mile hexagonal grid cells

  3. Interpolate population for each cell by area. If a cell is fully contained within a block group, then that cell receives a proportion of the block group’s population that is equal to the proportion of the block group’s area that the cell occupies (i.e., 1/10th square mile divided by block group’s area). Where grid cells overlap multiple block groups, populations from the several block groups are allocated proportionally.

  4. Download transit point data from OSM.

    • buses stops
    • tram stops
    • subway and light rail stations / stops
    • ferry terminals
  5. Find percentage of population within 0.5km to a transit stop.

    • Method 1: Are there any stops within the grid cell? A hexagon with an area of 1/10th of a square mile has a diagonal length (corner-to-corner) of roughly 0.5km. If a transit stop is in one corner of the cell, a resident living at the far corner could access it (as the crow flies).
    • Method 2: Are there any stops within 0.5km of the centroid of the grid cell as the crow flies? Effectively, this assumes the grid cell’s entire population lives at its centroid.
    • Method 3: Are there any stops with 0.5km of the centroid of the grid cell by walking distance? Still assumes the grid cell’s population lives at its centroid, but leverages OSM road data and the OpenSourceRoutingMachine (OSRM).

Method 1:

New Orleans has very few transit stops mapped, so an extremely low percentage of transit access is expected.

grids_summary <- readRDS("~objects/30/32_grids_summary.RDS")

for(i in seq_along(grids_summary)) {
  print(
      kable(grids_summary[[i]], caption = names(grids_summary)[i], longtable = F, align = "l") %>%
          kable_styling(font_size = 14, latex_options = "repeat_header", full_width = FALSE)
  )
}
Baltimore
hasTransit TotPop prop
no 104665 0.1702662
yes 510049 0.8297338
Minneapolis
hasTransit TotPop prop
no 64280 0.1560338
yes 347682 0.8439662
New Orleans
hasTransit TotPop prop
no 335271 0.860627
yes 54295 0.139373

An example of how the calculation was done for four of the grid cells

grids <- readRDS("~objects/30/32_grids.RDS")
pubTrans <- readRDS("~objects/20/22_pubTrans.RDS")

tm_shape(grids$Baltimore[c(462, 498, 534, 572),]) + tm_polygons(col = "blue", alpha = 0.3) +
  tm_shape(pubTrans$Baltimore) + tm_dots(col = "red")

Method 2:

This method is the broadest, so transit access is near 100% in Baltimore and Minneapolis.

buffers_summary <- readRDS("~objects/30/32_buffers_summary.RDS")

for(i in seq_along(buffers_summary)) {
  print(
      kable(buffers_summary[[i]], caption = names(buffers_summary)[i], longtable = F, align = "l") %>%
          kable_styling(font_size = 14, latex_options = "repeat_header", full_width = FALSE)
  )
}
Baltimore
hasTransit TotPop prop
no 19192 0.031221
yes 595522 0.968779
Minneapolis
hasTransit TotPop prop
no 8465 0.020548
yes 403497 0.979452
New Orleans
hasTransit TotPop prop
no 293554 0.7535411
yes 96012 0.2464589

Examples. The buffers are in orange, original grids in blue, bus stops in red.

# buffers <- readRDS("~objects/30/32_buffers.RDS")
# 
# tm_shape(buffers$Baltimore[c(462, 498, 534, 572),]) + tm_polygons(col = "orange", alpha = 0.5) +
#   tm_shape(grids$Baltimore[c(462, 498, 534, 572),]) + tm_polygons(col = "blue", alpha = 0.3) +
#   tm_shape(pubTrans$Baltimore) + tm_dots(col = "red")

Method 3:

This method gives results somewhere in between

isometric_summary <- readRDS("~objects/30/32_isometric_summary.RDS")

for(i in seq_along(isometric_summary)) {
  print(
      kable(isometric_summary[[i]], caption = names(isometric_summary)[i], longtable = F, align = "l") %>%
          kable_styling(font_size = 14, latex_options = "repeat_header", full_width = FALSE)
  )
}
Baltimore
hasTransit TotPop prop
no 56386 0.0917275
yes 558326 0.9082725
Minneapolis
hasTransit TotPop prop
no 28770 0.0698365
yes 383192 0.9301635
New Orleans
hasTransit TotPop prop
no 307432 0.7912086
yes 81128 0.2087914

Examples. The original grids are in blue, the grid centroid in green, the 0.5km walking distance in orange, and the bus stops in red

walkroads <- readRDS("~objects/20/~archive/22_walkroads.RDS")
isometric_list <- readRDS("~objects/30/32_isometric_list.RDS")

tmp <- st_intersection(walkroads$Baltimore,
                       isometric_list$Baltimore[c(462, 498, 534, 572),])
## Warning: attribute variables are assumed to be spatially constant throughout all
## geometries
centroid_tmp <- st_centroid(grids$Baltimore)
## Warning in st_centroid.sf(grids$Baltimore): st_centroid assumes attributes are
## constant over geometries of x
tm_shape(grids$Baltimore[c(462, 498, 534, 572),]) + tm_polygons(col = "blue", alpha = 0.3) +
  tm_shape(tmp) + tm_lines(col = "orange", lwd = 4) +
  tm_shape(centroid_tmp[c(462, 498, 534, 572),]) + tm_dots(col = "green", size = 1) +
  tm_shape(pubTrans$Baltimore) + tm_dots(col = "red")

Open Space SDG (11.7.1)

SDG target 11.7 is By 2030, provide universal access to safe, inclusive and accessible, green and public spaces, particularly for women and children, older persons and persons with disabilities. Source.

Sufficient public space is critical for cities to function effectively and grow equitably. Public spaces, which the UN defines as any “streets, sidewalks, squares, gardens, parks, and conservation areas” available for public use, support necessary infrastructure like fire hydrants and roadways, and green spaces in particular provide important public health and environmental benefits.

To track progress made on this SDG, the UN has proposed the following indicator: Area of public and green space as a proportion of total city space. The UN’s minimum standard for public space in urban areas is 45%, broken down into 30% for streets and sidewalks and 15% for green space.

Method

What percentages of Baltimore, Minneapolis, New Orleans, Philadelphia, Houston, and San Francisco consist of publicly accessible green space?

  1. Download the following OpenStreetMap features. Collect only the polygon/multipolygon features, as areas cannot be calculated for point or line features.
  • key=leisure
    • value=park
    • value=dog_park
    • value=garden
    • value=nature_reserve
    • value=pitch
    • value=playground
    • key=place, value=square
    • key=landuse, value=cemetery
  1. Download the same features (to the extent possible) from each city’s open data website. Some cities (e.g., Philadelphia) provide detailed land use maps that distinguish parks, ball fields, playgrounds, and cemeteries. Others (e.g. Houston) provide only shapefiles for city parks. These will serve as “control” datasets. How does this SDG indicator differ between measurements made on OSM data and municipality open data?

  2. Download US Census TIGER/Line boundaries and hydrologies for each city. Subtract the area of the hydrologies from the total area of the city to derive the land area for each city.

  3. Calculate the total area of park space features from OSM. Do the same for the open data features. Divide each sum by the city’s land area.

Results

Running list of questions / notes

  1. Each grid cell is 1/10th of a square mile. Any thoughts on how to calibrate that number? For context, Baltimore has 653 total block groups and 946 total grid cells using that size.

  2. As-the-crow-flies buffer. I set it as a 0.5km buffer from the cell’s centroid, but that assumes the entire population of the cell lives at the centroid. Is there a better way to do it / is it worth doing so?

  3. Some of the census tracts cover water (like Baltimore Harbor), meaning some cell centroids fall in the water, and they need to be auto-snapped to a roadway for finding walk distances. Probably not a big deal, but maybe clipping the tracts with the water features first is a good idea.

  4. For the transit SDG, should we be looking at a larger area? Looking at a city proper might not be as useful as a whole state (at least in areas above a minimum population density) or a greater metro area.

  5. Repeat the transit analysis but with reference datasets for transit?

  6. Check demographic/socio-economic averages among areas with and without transit. Might not be interesting given that transit access is over 90% in Baltimore and Minneapolis.

References

Installing a local OSRM server

Instructions: https://github.com/Project-OSRM/osrm-backend OSM extracts: http://download.geofabrik.de/

Example uses Minnesota

# download
wget http://download.geofabrik.de/north-america/us/minnesota-latest.osm.pbf -outfile C:\Users\echong\Documents\SummerOfMaps\OSMUS\OSRMdata\Minnesota\minnesota-latest.osm.pbf

# extra using foot.lua
docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-extract -p "/opt/foot.lua" "/data/minnesota-latest.osm.pbf"

# partition and custome
docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-partition "/data/minnesota-latest.osrm"
docker run -t -v "${PWD}:/data" osrm/osrm-backend osrm-customize "/data/minnesota-latest.osrm"

# launch!
docker run -t -i -p 5000:5000 -v "${PWD}:/data" osrm/osrm-backend osrm-routed --algorithm mld /data/minnesota-latest.osrm